/**
 * chenuu.com
 * 
 * @author  zhaoxu.com@gmail.com
 * @created 2012-11-17
 */
package com.chenuu.webapp.filters;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 *
 */
public class PerformanceFilter  implements Filter {

	private static final Log logger = LogFactory.getLog("PERF");

	/* (non-Javadoc)
	 * @see javax.servlet.Filter#destroy()
	 */
	@Override
	public void destroy() {
	}

	/* (non-Javadoc)
	 * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
	 */
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		String requestUrl = getRequestUrl(request);

		long startTime = System.currentTimeMillis();
		Throwable failed = null;
		try {
			chain.doFilter(request, response);
		} catch (Throwable e) {
			failed = e;
			logger.error("Exception ::: ", e);
		} finally {
			long duration = System.currentTimeMillis() - startTime;
			boolean succeed = failed == null;
			if (logger.isInfoEnabled()) { // && duration > 100) {
				logger.info("[" + requestUrl + "," + duration + "ms," + succeed
						+ "]");
			}
		}
		if (failed != null) {
			if (failed instanceof Error) {
				throw (Error) failed;
			} else if (failed instanceof RuntimeException) {
				throw (RuntimeException) failed;
			} else if (failed instanceof IOException) {
				throw (IOException) failed;
			} else if (failed instanceof ServletException) {
				throw (ServletException) failed;
			}
		}
	}

	/* (non-Javadoc)
	 * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
	 */
	@Override
	public void init(FilterConfig arg0) throws ServletException {
	}
	
	private String getRequestUrl(ServletRequest request) {
		HttpServletRequest req = (HttpServletRequest) request;
		StringBuffer buffer = new StringBuffer(req.getMethod());

		buffer.append(" ").append(req.getRequestURI());

		String queryString = StringUtils.trimToNull(req.getQueryString());

		if (queryString != null) {
			buffer.append("?").append(queryString);
		}

		return buffer.toString();
	}

}
